Welcome! While we're waiting:
Please download the workshop files from: https://github.com/dlab-geo/r-leaflet-workshop
Unzip the Zipfile: https://github.com/dlab-geo/r-leaflet-workshop/archive/master.zip
Open RStudio
Open a new R script file
Fall 2018
Welcome! While we're waiting:
Please download the workshop files from: https://github.com/dlab-geo/r-leaflet-workshop
Unzip the Zipfile: https://github.com/dlab-geo/r-leaflet-workshop/archive/master.zip
Open RStudio
Open a new R script file
Basic Maps
Data Maps
Doing More
This workshop/tutorial will walk you through the basics of using the Leaflet mapping package in R. You can follow along in any of the three formats:
Make sure you can copy and paste from one of the above into the script.
To begin, lets set up our packages and environment.
Load the packages we will use today
library(leaflet) library(RColorBrewer) library(sp) library(rgdal) library(htmlwidgets) library(magrittr) # or dplyr
Install any packages that you do not have on your computer
# install.packages("leaflet")
# install.packages("RColorBrewer")
# install.packages("sp")
# install.packages("rgdal")
# install.packages("htmlwidgets")
# install.packages("magrittr") # or dplyr
to the folder in which you unzipped the workshop files
Leaflet is a lightweight, yet powerful javascript library for creating interactive web maps.

Leaflet maps are a combination of HTML and Javascript code that is meant to be rendered in a web browser.
We can use the R leaflet package to create Leaflet maps in R
leaflet?There are a number of R packages for making Leaflet maps.
leaflet is actively maintained, highly customizable, and integrates well with other R libraries.
tmap is easier for getting started but less customizeable
map1 <- leaflet() # Initialize the map object map1 <- addTiles(map1) # Add basemap tiles map1 # Display the map
WARNING don't call your map object map
map1 <- leaflet() # Initialize the map object map1 <- addTiles(map1) # Add basemap tiles - default is OpenStreetMap map1 # Display the map
Specify the center and zoom level for the map
map1 <- leaflet() %>%
addTiles() %>%
setView(lat=37.870044, lng=-122.258169, zoom = 15)
map1
map1 # setView(lat=37.870044, lng=-122.258169, zoom = 15)
Chains commands so that the output of one command becomes the input of the next command.
map2 <- leaflet() %>%
addTiles() %>%
setView(lat=37.870044, lng=-122.258169, zoom = 15)
map2
Requires dplyr or magrittr package to be loaded
map2
Regular
map1 <- leaflet() map1 <- addTiles(map1) map1 <- setView(map1, lat=37.870044, lng=-122.258169, zoom = 15) map1
Piping
map2 <- leaflet() %>%
addTiles() %>%
setView(lat=37.870044, lng=-122.258169, zoom = 15)
map2
Create a leaflet map centered on the Doe Library
what's hereQuestions
By Default, Leaflet uses the OpenStreetMap basemap, which is added with the addTiles() function
leaflet() %>% addTiles() %>%
setView(lat=37.870, lng=-122.258, zoom = 15)
Use addProviderTiles with the name of the basemap to add a different basemap.
Create a leaflet map with the ESRI World Street Map basemap.
map2 <- leaflet() %>%
addProviderTiles("Esri.WorldStreetMap") %>%
setView(lat=37.870044, lng=-122.258169, zoom = 12)
map2 #Using ESRI WorldStreetMap basemap
Add a different basemap by taking a look at this web page of available basemaps
http://leaflet-extras.github.io/leaflet-providers/preview/
Use the provider name in quotes to access the basemap.
leaflet() %>% addProviderTiles("CartoDB.Positron") %>%
setView(lat=37.870044, lng=-122.258169, zoom = 12)
For more info, read the documentation
?addProviderTiles
Use addMarkers to add one or more data points to the map.
map3 <- leaflet() %>% addTiles() %>% addMarkers(lat=37.870044, lng=-122.258169, popup="Go Bears!") map3
map3 <- leaflet() %>% addTiles() %>% #setView(lat=37.870044, lng=-122.258169, zoom = 17) %>% addMarkers(lat=37.870044, lng=-122.258169, popup="Go Bears!") map3
The map will automatically center on the marker data and determine the zoom level.
You don't need to use setView (commented out).
But, you can override the default center & zoom by using setView.
What does popup= do?
?addMarkers
addMarkers(map, lng = NULL, lat = NULL, layerId = NULL, group = NULL, icon = NULL, popup = NULL, popupOptions = NULL, label = NULL, labelOptions = NULL, options = markerOptions(), clusterOptions = NULL, clusterId = NULL, data = getMapData(map))
How would you add a second marker for Cafe Milano?
37.868641, -122.258537
Try it?
map3 <- leaflet() %>% addTiles() %>% addMarkers(lat=37.870044, lng=-122.258169, popup="Go Bears!") %>% addMarkers(lat=37.868641, lng=-122.258537, popup="Cafe Milano") map3
map3 <- leaflet() %>%
addTiles() %>%
addMarkers(lat = c(37.870044,37.868641),
lng = c(-122.258169,-122.258537),
popup = c("Go Bears", "Cafe Milano"))
map3
Source: Caltrans GIS Data
bart <- read.csv('data/bart.csv', stringsAsFactors = FALSE)
str(bart)
## 'data.frame': 44 obs. of 6 variables: ## $ X : num -122 -122 -122 -122 -122 ... ## $ Y : num 37.9 37.9 37.9 37.8 37.8 ... ## $ STATION : chr "NORTH BERKELEY" "DOWNTOWN BERKELEY" "ASHBY" "ROCKRIDGE" ... ## $ OPERATOR: chr "BART" "BART" "BART" "BART" ... ## $ DIST : int 4 4 4 4 4 4 4 4 4 4 ... ## $ CO : chr "ALA" "ALA" "ALA" "ALA" ...
What column(s) contain the geographic data?
map4 <- leaflet() %>%
addTiles() %>%
addMarkers(lat=bart$Y, lng=bart$X,
popup= paste("Station:", bart$STATION))
map4
map4
Point data are often stored in CSV files and loaded into R data frames.
These point data are manipulated like other R data frames.
Leaflet can map these data if the points use geographic coordinates (longitude & latitude).
More complex geographic data are commonly stored in ESRI Shapefiles.
To get the most out of spatial data in R you should use packages specifically for working with spatial data.
We can use the sp and rgdal packages to import, manipulate and map more complex spatial objects.
sp - R classes and methods for spatial data
rgdal - Functions for importing and transforming spatial data
Let's use these to import data in ESRI Shapefiles
BART Lines
Source: Caltrans GIS Data
dir("data/BART_13/")
## [1] "BART_13.dbf" "BART_13.prj" "BART_13.sbn" "BART_13.sbx" ## [5] "BART_13.shp" "BART_13.shp.xml" "BART_13.shx"
Use rgdal to read in the data from a Shapefile
library(rgdal) bart_lines <- readOGR(dsn="data/BART_13",layer="BART_13")
## OGR data source with driver: ESRI Shapefile ## Source: "data/BART_13", layer: "BART_13" ## with 6 features ## It has 3 fields
Take a look at the data
summary(bart_lines)
## Object of class SpatialLinesDataFrame ## Coordinates: ## min max ## x -122.47113 -121.89932 ## y 37.55675 38.02386 ## Is projected: FALSE ## proj4string : ## [+proj=longlat +datum=NAD83 +no_defs +ellps=GRS80 +towgs84=0,0,0] ## Data attributes: ## ROUTE Shape_Leng LINE ## Dublin/Pleasanton to Daly City :1 Min. : 3686 Blue :1 ## Fremont to Daly City :1 1st Qu.:62836 Green :1 ## Fremont to Richmond :1 Median :64169 Orange:1 ## Millbrae to SFO Shuttle :1 Mean :58883 Red :1 ## Pittsburg/Bay Point to SFO to Millbrae:1 3rd Qu.:64962 Yellow:1 ## Richmond to Daly City to Millbrae :1 Max. :93658 NA's :1
Use addPolyLines to add linear features
map4 <- leaflet() %>%
addTiles() %>%
addMarkers(lat=bart$Y, lng=bart$X,
popup= paste("Station:", bart$STATION)) %>%
addPolylines(data=bart_lines, color="red", weight=3)
map4
Leaflet can map both data frames & spatial objects!
map4
Let's add BART Service Area data from the Metropolitan Transportation Commission (MTC)
dir("data/Transit_Service_Areas_2016")
## [1] "bart_service_area.dbf" "bart_service_area.prj" ## [3] "bart_service_area.qpj" "bart_service_area.shp" ## [5] "bart_service_area.shx" "Transit_Service_Areas_2016.cpg" ## [7] "Transit_Service_Areas_2016.dbf" "Transit_Service_Areas_2016.prj" ## [9] "Transit_Service_Areas_2016.shp" "Transit_Service_Areas_2016.shx" ## [11] "Transit_Service_Areas_2016.xml"
Let's add BART Service Area data from the Metropolitan Transportation Commission (MTC)
bart_service <- readOGR(dsn="data/Transit_Service_Areas_2016",layer="bart_service_area")
## OGR data source with driver: ESRI Shapefile ## Source: "data/Transit_Service_Areas_2016", layer: "bart_service_area" ## with 3 features ## It has 7 fields ## Integer64 fields read as strings: OBJECTID
Take a look at the data
summary(bart_service)
## Object of class SpatialPolygonsDataFrame ## Coordinates: ## min max ## x -122.47784 -121.77617 ## y 37.32445 38.02598 ## Is projected: FALSE ## proj4string : ## [+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0] ## Data attributes: ## OBJECTID agency_id agency_nam status system ## 13:1 BA:3 BART:3 Existing :1 Rail:3 ## 14:1 Planned :1 ## 15:1 Under Construction:1 ## ## ## ## Shape__Are Shape__Len ## Min. : 9885713 Min. : 22981 ## 1st Qu.:10027470 1st Qu.: 24130 ## Median :10169227 Median : 25279 ## Mean :35531127 Mean : 84825 ## 3rd Qu.:48353833 3rd Qu.:115747 ## Max. :86538439 Max. :206215
Use addPolygons to add area features
map4 <- leaflet() %>%
addTiles() %>%
addMarkers(lat=bart$Y, lng=bart$X,
popup= paste("Station:", bart$STATION)) %>%
addPolylines(data=bart_lines, color="red", weight=3) %>%
addPolygons(data=bart_service, color="blue", opacity = 0.6)
map4
map4
Redo the previous map and:
change the basemap to "CartoDB.Positron"
set the default view to center on San Francisco
Save the map as an HTML file that you can then open in a browser, share with friends, put online.
#library(htmlwidgets) saveWidget(map4, file="bartmap.html")
San Francisco Open Data Portal
This data set includes the Office of the Assessor-Recorder’s secured property tax roll spanning from 2015.
We are using this as a proxy for home values.
We are working with a simplified version of the full data set.
Set your working directory first to the folder where you downloaded the workshop files!
sfhomes <- read.csv('data/sfhomes15.csv', stringsAsFactors = FALSE)
str(sfhomes)
## 'data.frame': 680 obs. of 11 variables: ## $ SalesDate : chr "2015-08-21" "2015-08-13" "2015-12-29" "2015-07-06" ... ## $ Address : chr "0000 2760 19TH AV0015" "0000 0560AMISSOURI ST0000" "0000 0718 LONG BRIDGE ST1202" "0000 0899 VALENCIA ST0202" ... ## $ YrBuilt : int 1979 2003 2016 2015 1961 1900 2015 NA 1947 1907 ... ## $ NumBeds : int 2 2 2 3 3 2 2 0 0 3 ... ## $ NumBaths : int 2 2 2 3 3 2 2 0 0 3 ... ## $ NumUnits : int 1 1 1 1 1 1 1 1 1 1 ... ## $ AreaSqFt : int 1595 1191 1346 1266 1840 1256 1520 536 950 1837 ... ## $ Neighborhood: chr "Twin Peaks" "Potrero Hill" "Mission Bay" "Mission" ... ## $ Value : int 865000 1402560 2260993 1700000 2309692 2700564 1925000 583768 944180 1750001 ... ## $ lat : num 37.7 37.8 37.8 37.8 37.8 ... ## $ lon : num -122 -122 -122 -122 -122 ...
head(sfhomes)
## SalesDate Address YrBuilt NumBeds NumBaths ## 1 2015-08-21 0000 2760 19TH AV0015 1979 2 2 ## 2 2015-08-13 0000 0560AMISSOURI ST0000 2003 2 2 ## 3 2015-12-29 0000 0718 LONG BRIDGE ST1202 2016 2 2 ## 4 2015-07-06 0000 0899 VALENCIA ST0202 2015 3 3 ## 5 2015-06-12 0000 1333 JONES ST0808 1961 3 3 ## 6 2015-04-14 0000 1904 BAKER ST0000 1900 2 2 ## NumUnits AreaSqFt Neighborhood Value lat lon ## 1 1 1595 Twin Peaks 865000 37.73601 -122.4741 ## 2 1 1191 Potrero Hill 1402560 37.75920 -122.3965 ## 3 1 1346 Mission Bay 2260993 37.77181 -122.3942 ## 4 1 1266 Mission 1700000 37.75876 -122.4210 ## 5 1 1840 Nob Hill 2309692 37.79362 -122.4149 ## 6 1 1256 Pacific Heights 2700564 37.78881 -122.4437
map4 <- leaflet() %>%
addTiles() %>%
addMarkers(lat=sfhomes$lat, lng=sfhomes$lon,
popup= paste("Address:", sfhomes$Address,
"<br>", # add line break
"Property Value: ", sfhomes$Value))
map4
We can add to and save the popup code and re-use it instead of typing it over and over again.
popup_content <- paste("<b>Address:</b>", sfhomes$Address,"<br>",
"<b>Property Value</b>: ", sfhomes$Value, "<br>",
"<b>Neighborhood:</b> ", sfhomes$Neighborhood, "<br>",
"<b>Num Bedrooms: </b>", sfhomes$NumBeds, "<br>",
"<b>Num Bathrooms:</b>", sfhomes$NumBaths
)
map4 <- leaflet() %>%
addTiles() %>%
addMarkers(lat=sfhomes$lat, lng=sfhomes$lon,
popup= popup_content)
map4
Instead of this:
leaflet() %>% addTiles() %>% addMarkers(lat=sfhomes$lat, lng=sfhomes$lon, popup= popup_content)
We can use this syntax:
leaflet(sfhomes) %>% addTiles() %>% addMarkers(~lon, ~lat, popup = popup_content)
When the addMarkers function arguments lng= and lat= are not named they must be in the expected order (longitude, latitude)!
Read the addMarker documentation for options to address this.
addMarkers(map, lng = NULL, lat = NULL, layerId = NULL,
group = NULL, icon = NULL, popup = NULL,
options = markerOptions(),
clusterOptions = NULL, clusterId = NULL,
data = getMapData(map))
map4 <- leaflet(sfhomes) %>%
addTiles() %>%
addMarkers(~lon, ~lat, popup= popup_content,
clusterOptions = 1)
map4 # Explore the Map - hover over a cluster marker, zoom in.
addCircleMarker
map4 <- leaflet(sfhomes) %>% addTiles() %>% addCircleMarkers(~lon, ~lat, popup = popup_content)
addCircleMarker
map4
addCircleMarkers(map, lng = NULL, lat = NULL, radius = 10,
layerId = NULL, group = NULL, stroke = TRUE, color = "#03F",
weight = 5, opacity = 0.5,
fill = TRUE, fillColor = color, ....)
Change color, radius and stroke weight of circle markers
map4 <- leaflet(sfhomes) %>%
addTiles() %>%
addCircleMarkers(~lon, ~lat, popup = popup_content,
color="white", radius=6, weight=2, # stroke
fillColor="red",fillOpacity = 0.75 # fill
)
colors() to see a list of all R named colors.map4
Can you cluster circleMarkers?
Use data values to determine the color and size of symbols.
We can symbolize the size of points by data values by making the radius of the circle a function of a data value.
map4 <- leaflet(sfhomes) %>%
addProviderTiles("CartoDB.Positron") %>%
addCircleMarkers(~lon, ~lat, popup=popup_content,
fillColor= NA, color="Red", weight=1, fillOpacity = 0,
radius= ~NumBeds+2
)
map4 # Size is a function of what variable?
Circles and CircleMarkers look quite similar.
Circle radii are specified in meters while CircleMarkers are specified in pixels.
map4b <- leaflet(sfhomes) %>%
addProviderTiles("CartoDB.Positron") %>%
addCircles(~lon, ~lat, popup=popup_content,
fillColor= NA, color="Red",
weight=1, fillOpacity = 0,
radius= ~NumBeds*10
)
Circle radii are specified in meters not pixels - Zoom in to see how it works.
map4b # Compare map4 and map4b at different zoom levels


The RColorBrewer package is widely used to create color palettes for maps.
There are 3 types of color palettes
Qualitative Color PalettesSequential Color PalettesDiverging Color PalettesContrasting colors for categorical data
display.brewer.all(type="qual")
display.brewer.pal(7, "Set3" ) # Try a different number of colors
For highlighting trends in numerical data
display.brewer.all(type="seq")
For highlighting the outliers
display.brewer.all(type="div")
Let's map sfhomes by the values in the Neighborhood column.
First, check out the RColorBrewer qualitative color palettes
display.brewer.all(type="qual")
colorfactor takes as input a color palette and a domain that contains the full range of possible values to be mapped.
colorfactor returns a function specific to that domain that can be used to output a set of color values.
# Create a qualitative color palette
myColor_function <- colorFactor("Paired", sfhomes$Neighborhood)
map4 <- leaflet(sfhomes) %>%
addProviderTiles("CartoDB.Positron") %>%
addCircleMarkers(~lon, ~lat,
popup= popup_content,
fillColor= ~myColor_function(Neighborhood),
radius=6, color=NA, weight=2, fillOpacity = 1
)
map4 # what neighborhood had the most 2015 transactions?
map4 <- leaflet(sfhomes) %>%
addProviderTiles("CartoDB.Positron") %>%
addCircleMarkers(~lon, ~lat, popup=popup_content,
fillColor= ~myColor_function(Neighborhood),
radius=6, color=NA, weight=2,fillOpacity = 1
) %>%
addLegend(title = "Neighborhood", pal = myColor_function,
values = ~Neighborhood, opacity = 1,
position="bottomleft")
map4
For mapping colors to qualitative data
?colorfactor
colorFactor(palette, domain, levels = NULL, ordered = FALSE, na.color = "#808080", alpha = FALSE, reverse = FALSE)
Let's map the homes by value.
First, check out the sequential color palettes
display.brewer.all(type="seq")
For simple linear scaling of colors to values use colorNumeric.
First, create the color mapping function
numColor_function <- colorNumeric("Reds", sfhomes$Value)
Use the numColor_function to create a proportional color map
map4 <- leaflet(sfhomes) %>%
addProviderTiles("CartoDB.Positron") %>%
addCircleMarkers(~lon, ~lat, popup=popup_content,
fillColor= ~numColor_function(Value),
radius=6, color="grey", weight=1, fillOpacity = 1
) %>%
addLegend(title = "Property Values", pal = numColor_function,
values = ~Value, opacity = 1,
position="bottomleft")
map4 # proportional color map
For simple linear scaling of colors to values use colorNumeric.
?colorNumeric
colorNumeric(palette, domain, na.color = "#808080", alpha = FALSE, reverse = FALSE)
Use colorQuantile to create a color palette based on quantile binning of the data.
First, create the color mapping function
quantColor_function <- colorQuantile("Reds", sfhomes$Value, n=5)
Use the color function to map colors to house values
map4b <- leaflet(sfhomes) %>%
addProviderTiles("CartoDB.Positron") %>%
addCircleMarkers(~lon, ~lat, popup=popup_content,
fillColor= ~quantColor_function(Value),
radius=6, color="grey", weight=1,fillOpacity = 1
)
map4b # Graduated color map
For mapping colors to data binned by quantiles
?colorQuantile
colorQuantile(palette, domain, n = 4, probs = seq(0, 1, length.out = n + 1), na.color = "#808080", alpha = FALSE, reverse = FALSE)
For more control over customizing colors see the colorBin function which can be used to create color palettes based on different classification methods for binning the data, eg equal interval, natural breaks etc.
?colorBin
map4b %>% addLegend(title = "Value", pal = quantColor_function,
values = ~Value, opacity = 1,
position="bottomleft")
map5 <-map4b %>% addLegend(pal = quantColor_function, values = ~Value,
title = "Property Value, 2015",
position="bottomleft",
opacity=1,
labFormat = function(type, cuts, p) {
n = length(cuts)
cuts = paste0("$", format(cuts[-n], big.mark=","),
" - ", "$",format(cuts[-1], big.mark=","))
}
)
map5 # Graduated Color Map
Basic Maps
addMarkers - Simple Marker MapsaddCircleMarkers - Circle Marker MapsData Maps
addCircles Proportional symbol mapscolorFactor - Category MapscolorNumeric - Proportional color mapscolorQuantile - Graduated color mapsColor areas based on data values.
The data values are classified into bins.
Quantile classification is the default.
Each bin gets a unique color from a color palette.
sf_md_hhi <- readOGR(dsn="data",layer="sf_medhhincome_acs5y_16")
## OGR data source with driver: ESRI Shapefile ## Source: "data", layer: "sf_medhhincome_acs5y_16" ## with 196 features ## It has 5 fields
summary(sf_md_hhi)
## Object of class SpatialPolygonsDataFrame ## Coordinates: ## min max ## x -123.01392 -122.32756 ## y 37.69274 37.86334 ## Is projected: FALSE ## proj4string : ## [+proj=longlat +datum=NAD83 +no_defs +ellps=GRS80 +towgs84=0,0,0] ## Data attributes: ## GEOID ## 06075010100: 1 ## 06075010200: 1 ## 06075010300: 1 ## 06075010400: 1 ## 06075010500: 1 ## 06075010600: 1 ## (Other) :190 ## NAME variable ## Census Tract 101, San Francisco County, California: 1 B19013_001:196 ## Census Tract 102, San Francisco County, California: 1 ## Census Tract 103, San Francisco County, California: 1 ## Census Tract 104, San Francisco County, California: 1 ## Census Tract 105, San Francisco County, California: 1 ## Census Tract 106, San Francisco County, California: 1 ## (Other) :190 ## estimate moe ## Min. : 11971 Min. : 739 ## 1st Qu.: 65893 1st Qu.: 9744 ## Median : 89668 Median :15343 ## Mean : 91151 Mean :16211 ## 3rd Qu.:117922 3rd Qu.:20032 ## Max. :205865 Max. :89454 ## NA's :2 NA's :2
Map sf_md_hhi with addPolygons
map6 <- leaflet() %>% addTiles() %>% addPolygons(data=sf_md_hhi)
map6 # using addPolygons to map sf_md_hhi
?addPolygons
addPolygons(map, lng = NULL, lat = NULL, layerId = NULL, group = NULL,
stroke = TRUE, color = "#03F", weight = 5, opacity = 0.5,
fill = TRUE, fillColor = color, fillOpacity = 0.2,
dashArray = NULL, smoothFactor = 1, noClip = FALSE,
popup = NULL, popupOptions = NULL, label = NULL,
labelOptions = NULL, options = pathOptions(),
highlightOptions = NULL, data = getMapData(map))
map6 <- leaflet() %>%
setView(lng=-122.448889, lat=37.764645, zoom=12) %>%
addProviderTiles("CartoDB.Positron") %>%
# Customize the symbology of the polygons
addPolygons(data=sf_md_hhi, color="grey", weight=1,
fillColor="Orange", fillOpacity = 0.25)
map6 # color="grey", weight=1, fillColor="Orange", fillOpacity = 0.25
Median Household Income is in the estimate column
Recipe:
estimate#display.brewer.all(type="seq")
Then create the color mapping function
##
quantColor_function <- colorQuantile("YlOrRd", sf_md_hhi$estimate, n=5)
A choropleth map is a graduated color map of polygon data.
map6 <- leaflet() %>%
setView(lng=-122.448889, lat=37.764645, zoom=12) %>%
addProviderTiles("CartoDB.Positron") %>%
#
addPolygons(data=sf_md_hhi,
color="white",
weight=1,
opacity=0.5,
fillColor=~quantColor_function(estimate),
fillOpacity = 0.65,
popup = paste0("$",sf_md_hhi$estimate))
map6 # choropleth map of median household income by census tract
map6 <- map6 %>% addLegend(pal = quantColor_function,
values = sf_md_hhi$estimate,
title = "Median HH Income",
position="bottomleft",
opacity=1,
labFormat = function(type, cuts, p) {
n = length(cuts)
cuts = paste0("$", format(cuts[-n], big.mark=","),
" - ", "$",format(cuts[-1], big.mark=","))
}
)
map6
You can add multiple data layers to a leaflet map.
Let's add the sfhomes to the map
cheap <- sfhomes[sfhomes$Value < 1000000,]
map7 <- leaflet() %>%
setView(lng=-122.448889, lat=37.764645, zoom=12) %>%
addProviderTiles("CartoDB.Positron") %>%
# Median household income polygons
addPolygons(data=sf_md_hhi, color="white", weight=1, opacity=0.5,
fillColor=~quantColor_function(estimate), fillOpacity = 0.65,
popup = paste0("$",sf_md_hhi$estimate)) %>%
# sfhomes points
addCircleMarkers(data=cheap, popup=paste0("$",cheap$Value),
color="black",weight=1, radius=6,
fillColor="white", fillOpacity = 0.75)
map7 # sfhomes and median household income
We can add a layer switcher control with addLayersControl().
This allows us to toggle on/off the display of a map layer.
First, we need to assign a group to each map layer
?addLayersControl
map8 <- leaflet() %>%
setView(lng=-122.448889, lat=37.764645, zoom=12) %>%
addProviderTiles("CartoDB.Positron") %>%
addPolygons(data=sf_md_hhi, color="white", weight=1, opacity=0.5,
fillColor=~quantColor_function(estimate), fillOpacity = 0.65,
popup = paste0("$",sf_md_hhi$estimate),
group="Median HH Income"
) %>%
addCircleMarkers(data=cheap, popup=paste0("$",cheap$Value),
color="black",weight=1, radius=6,
fillColor="white", fillOpacity = 0.75,
group="Property Values"
) %>%
addLayersControl(
overlayGroups = c("Property Values","Median HH Income"),
options = layersControlOptions(collapsed = FALSE)
)
map8
map8 <- leaflet() %>%
setView(lng=-122.448889, lat=37.764645, zoom=12) %>%
addProviderTiles("CartoDB.Positron", group="Simple Basemap") %>%
addProviderTiles("Esri.WorldStreetMap", group="Streets Basemap") %>%
addTiles("", group="No Basemap") %>%
#
addPolygons(data=sf_md_hhi, color="white", weight=1, opacity=0.5,
fillColor=~quantColor_function(estimate), fillOpacity = 0.65,
popup = paste0("$",sf_md_hhi$estimate),
group="Median HH Income"
) %>%
addCircleMarkers(data=cheap, popup=paste0("$",cheap$Value),
color="black",weight=1, radius=6,
fillColor="white", fillOpacity = 0.75,
group="Property Values"
) %>%
addLayersControl(
baseGroups = c("Simple Basemap", "Streets Basemap", "No Basemap"),
overlayGroups = c("Property Values","Median HH Income"),
options = layersControlOptions(collapsed = FALSE)
)
map8
Interactive Maps in R - check
Web Maps can be shared if online.
Easy way to go is RPubs
You can share you map online by publishing it to RPubs.
RPubs account to make that work.Enter the code for your map in the console
In the Viewer window, click on the Publish icon.
Another way to share your map is to save it to a file. You can then email it, host it on your own web server or host it on github, etc.
#library(htmlwidgets) saveWidget(map7, file="testmap.html")
Open your file to by double-clicking on it in the Mac Finder or Windows Explorer.
leaflet mapsFlexdashboard
Shiny
Crosstalk
Flexdashboard is a tool for creating interactive dashboards with R Markdown.
A framework for creating interactive web apps based on R code.
http://www.shinyapps.io - A freemium web platform for hosting your shiny apps.
An R package for creating interactive web documents without needing a server.
https://rstudio.github.io/crosstalk
More functionality than Flexdashboard, less than Shiny
Getting more Practice
To you!
and to Josh Pepper who did an earlier workshop on which these materials are loosely based.
You can add an online, georectified scanned map to leaflet.
There are many of these online at the New York Public Library or MapWarper, and other websites.
Let's add this map of Berkeley in 1880
Here we are combining addTiles and addProviderTiles
mapurl <- "https://mapwarper.net/maps/tile/25477/{z}/{x}/{y}.png"
map2 <- leaflet() %>%
addProviderTiles("CartoDB.Positron") %>%
addTiles(mapurl) %>% # custom map image
setView(lat=37.870044, lng=-122.258169, zoom = 13)
map2 # Map of Berkeley, 1880 overlaid on the CartoDB basemap